﻿// CShowCrack.cpp: 实现文件
//

#include "stdafx.h"
#include "CK103.h"
#include "CShowCrack.h"
#include "FileSys/CImgOperator.h"
#include "UI/MyImgBtn.h"
#include "define.h"

extern const CString strZoomIn[MAX_IMG_CNT];
extern const CString strZoomOut[MAX_IMG_CNT];
extern const CString strBtnPrevious[MAX_IMG_CNT];
extern const CString strBtnNext[MAX_IMG_CNT];

extern const CString strImgZoom;
extern const CString strImgZoomSel;

//const int		nMinCtrlWidth = 1000;		// 控件宽度
//const int		nMinCtrlHeight = 600;		// 控件高度

/////////////////////
//U8  4:3
const int		nImgWidth_U8 = 1024;			// 控件中图片显示区域宽度  800
const int		nImgHeight_U8 = 768;			// 控件中图片显示区域高度  480

//U9  4:3
const int		nImgWidth_U9 = 1280;			// 控件中图片显示区域宽度  
const int		nImgHeight_U9 = 800;			// 控件中图片显示区域高度  

//CK103  16:9
const int		nImgWidth = 1280;			// 控件中图片显示区域宽度  
const int		nImgHeight = 720;			// 控件中图片显示区域高度  
/////////////////////


const int		nZoomWidth = 720;			// 缩放条宽度
const int		nZoomHeight = 50;			// 缩放条高度
const int		nRadiusIn = 14;				// 缩放条内 内圈半径
const int		nRadiusOut = 15;			// 缩放条内 外圈半径

const int		nJudge = 30;				// 判断鼠标是否在指定范围内，可修改点距离

const double	dZoomMax = 2.5;				// 图像做的缩放尺寸
const double	dZoomMin = 1.0;				// 图像最小缩放尺寸
const double	dZoomDiv = 0.5;				// 图像缩放增加

#define REDRAW_ALL		((1 << 3) - 1)		// 重绘整个控件 
#define REDRAW_IMG		0x00000001			// 重绘图像
#define REDRAW_ZOOM		0x00000002			// 重绘放大功能区
#define REDRAW_BTN		0x00000004			// 重绘上一个下一个按键

#define IDC_BTN_PREVIOUS	5000
#define IDC_BTN_NEXT		5001
#define IDC_BTN_ZOOMIN		5002
#define IDC_BTN_ZOOMOUT		5003

// CShowCrack

IMPLEMENT_DYNAMIC(CShowCrack, CWnd)

CShowCrack::CShowCrack() :
	m_bGray(false),
	m_dCoe(dZoomMin),
	m_bLBtnDown(FALSE),
	m_nCurGJ(-1),
	m_brBack(RGB(255, 255, 255)),
	m_nLastSelPt(0),
	m_nCurSelPt(0),
	m_bPtSel(FALSE)
{
	RegisterWndClass();
}

CShowCrack::~CShowCrack()
{
	DeleteBtn();
}

void CShowCrack::initRect()
{
	int nX, nY;
	int nHDiv = 0;

	//m_rtCtrl = CRect(0, 0, nCtrlWidth, nCtrlHeight);
	this->GetClientRect(m_rtCtrl);

	// 图像绘制区域
	nX = (int)(m_rtCtrl.Width() * 53.0 / 78.0);
//	nY = (int)(nX * 9 / 16.0);			// 比例3：5
//	nY = (int)(nX * 3 / 5.0);			// 比例3：5
	
//////////////////////
	//by qzg 2019.10.21
	int nIdx = g_GJData.GetSelGJId();
	CString strYiQiType = g_GJData.GetYiQiType(nIdx);

	int		nImgWid = 1024;
	nY = (int)(nX * 3 / 4.0);			// 比例3：4
	nHDiv = (m_rtCtrl.Height() - nY - nZoomHeight) / 3;

	if (strYiQiType == strYiQi_U8_1024_768)
	{
		nY = (int)(nX * 3 / 4.0);			// 比例3：4
		nHDiv = (m_rtCtrl.Height() - nY - nZoomHeight) / 3;
		nImgWid = nImgWidth_U8;
	}
	else if (strYiQiType == strYiQi_U9_1280_800)
	{
		nY = (int)(nX * 10 / 16.0);			// 比例16：10
		nHDiv = (m_rtCtrl.Height() - nY - nZoomHeight) / 3;
		nImgWid = nImgWidth_U9;
	}
	else if (strYiQiType == strYiQi_CK103_1280_720)
	{
		nY = (int)(nX * 9 / 16.0);			// 比例9：16
		nHDiv = (m_rtCtrl.Height() - nY - nZoomHeight) / 3;
		nImgWid = nImgWidth;
	}
//	int nImgWid = 1280;
////////////////////

	m_dImgCoe = nX / (double)nImgWid;			//m_dImgCoe为宽度宽度/图片宽度比例系数

	m_rtImg = CRect((m_rtCtrl.Width() - nX) / 2, m_rtCtrl.top + nHDiv, (m_rtCtrl.Width() + nX) / 2, nY + nHDiv);

	// 放大功能区
	nX = m_rtImg.left + nRadiusOut * 2 + 10;
	nY = m_rtImg.bottom + nHDiv;
	m_rtZoom = CRect(nX, nY, m_rtImg.Width() - (nRadiusOut * 2 + 10) * 2 + nX, nY + nZoomHeight);

	m_rtBtnZoomIn = CRect(m_rtImg.left, m_rtZoom.top, nX - 10, m_rtZoom.top + nRadiusOut * 2);
	m_rtBtnZoomOut = CRect(m_rtZoom.right + 10, m_rtZoom.top, m_rtImg.right, m_rtZoom.top + nRadiusOut * 2);

	// 上一个下一个按键区域
	nX = (m_rtCtrl.Width() - 20 - m_rtImg.Width()) / 2;
	nY = (m_rtImg.Height() - nX) / 2 + m_rtImg.top;
	m_rtBtnPrevious = CRect(m_rtCtrl.left + 5, nY, m_rtCtrl.left + nX + 5, nY + nX);
	m_rtBtnNext = CRect(m_rtCtrl.right - nX - 5, nY, m_rtCtrl.right - 5, nY + nX);

	// 计算每一个缩放点的具体位置
	int nPtCnt = (int)(ceil((dZoomMax - dZoomMin) / dZoomDiv + 1));		// 进一法
	nX = (int)((m_rtZoom.Width() - nRadiusOut * 2) / (dZoomMax - dZoomMin) * dZoomDiv);
	nY = m_rtZoom.top + nRadiusOut;

	m_arrPtZoomValue.RemoveAll();
	for (int i = 0; i < nPtCnt; i++)
	{
		POINT pt;
		pt.x = nX * i + nRadiusOut + m_rtZoom.left;
		if (pt.x > m_rtZoom.right - nRadiusOut || i == nPtCnt - 1)
		{
			pt.x = m_rtZoom.right - nRadiusOut;
		}
		pt.y = nY;

		m_arrPtZoomValue.Add(pt);
	}
}

void CShowCrack::initImg(const int& nIdx, bool bNew, bool bGray)
{
	if (m_nCurGJ != nIdx || bNew)
	{
		m_ptImgMouse.x = 0;
		m_ptImgMouse.y = 0;

		m_ptLeftTop.x = 0;
		m_ptLeftTop.y = 0;

		m_dCoe = dZoomMin;

		m_nCurGJ = nIdx;

		m_imgOperator.SetImgInfo(nIdx);
	}
	
	m_bGray = bGray;
	m_nLastSelPt = 0;
	m_nCurSelPt = 0;

	m_imgOperator.DrawCrackInfo(DRAW_CRACK | DRAW_CRACKRULE | DRAW_CRACKWIDTH, 0, bGray);
	
	DrawCtrl(REDRAW_IMG | REDRAW_ZOOM);
}

void CShowCrack::ZoomIn()
{
	CPoint ptCur;
	double dCoeLast;

	ptCur.x = m_rtImg.left + m_rtImg.Width() / 2;
	ptCur.y = m_rtImg.top + m_rtImg.Height() / 2;

	dCoeLast = m_dCoe;
	CalcDCoe((-1) * dZoomDiv);
	CalcLeftTopPt(ptCur, dCoeLast);
	DrawCtrl(REDRAW_IMG | REDRAW_ZOOM);
}

void CShowCrack::ZoomOut()
{
	CPoint ptCur;
	double dCoeLast;

	ptCur.x = m_rtImg.left + m_rtImg.Width() / 2;
	ptCur.y = m_rtImg.top + m_rtImg.Height() / 2;

	dCoeLast = m_dCoe;
	CalcDCoe(dZoomDiv);
	CalcLeftTopPt(ptCur, dCoeLast);
	DrawCtrl(REDRAW_IMG | REDRAW_ZOOM);
}

float CShowCrack::FindCrack()
{
	int nIdx = g_GJData.GetSelGJId();
	float fAvg = g_GJData.GetGJImgAvg(nIdx);
	/*POINT pt1, pt2;
	if (m_imgOperator.FindCrack(pt1, pt2, fAvg))
	{
		g_GJData.SetFirstPoint(pt1, nIdx);
		g_GJData.SetSecPoint(pt2, nIdx);
		//g_GJData.SetGJImgAvg(fAvg, nIdx);

		float fWth = g_GJData.CalcCrack(nIdx);
		m_imgOperator.SetCrackWidth(fWth);
		m_imgOperator.SetGray(fAvg);
		m_imgOperator.DrawCrackInfo(DRAW_CRACK | DRAW_CRACKRULE | DRAW_CRACKWIDTH, 0, m_bGray);

		DrawCtrl(REDRAW_IMG);

		return fWth;
	}	// */

	int			nHight = 0;
	CString strYiQiType = g_GJData.GetYiQiType(nIdx);

	if (strYiQiType == strYiQi_U8_1024_768)
	{
		nHight = nImgHeight_U8;
	}
	else if (strYiQiType == strYiQi_U9_1280_800)
	{
		nHight = nImgHeight_U9;
	}
	else if (strYiQiType == strYiQi_CK103_1280_720)
	{
		nHight = nImgHeight;
	}

	if (g_GJData.ResetPoint(nHight, nIdx))
	{
		m_imgOperator.SetPoint1(g_GJData.GetFirstPoint(nIdx));
		m_imgOperator.SetPoint2(g_GJData.GetSecPoint(nIdx));

		float fWth = g_GJData.CalcCrack(nIdx);
		m_imgOperator.SetCrackWidth(fWth);
		m_imgOperator.SetGray(fAvg);
		m_imgOperator.DrawCrackInfo(DRAW_CRACK | DRAW_CRACKRULE | DRAW_CRACKWIDTH, 0, m_bGray);

		DrawCtrl(REDRAW_IMG);

		return fWth;
	}
	
	return g_GJData.GetCrackWidth(nIdx);
}

void CShowCrack::DrawCtrl(int nRedrawFlag)
{
	CClientDC	dc(this);					// 增加双缓冲绘图 避免闪烁
	CDC			MemDC;
	CBitmap		MemBitmap, *pOldBit;
	int			nWidth, nHeight;

	nWidth = m_rtCtrl.Width();
	nHeight = m_rtCtrl.Height();

	MemDC.CreateCompatibleDC(&dc);
	MemBitmap.CreateCompatibleBitmap(&dc, nWidth, nHeight);

	//将位图选入到内存显示设备中
	pOldBit = MemDC.SelectObject(&MemBitmap);

	//先用背景色将位图清除干净，这里我用的是白色作为背景
	MemDC.FillSolidRect(0, 0, nWidth, nHeight, RGB(255, 255, 255));

	if (nRedrawFlag == REDRAW_ALL)
	{
		//MemDC.FillSolidRect(m_rtCtrl, RGB(255, 255, 255));

		MemDC.MoveTo(m_rtImg.left - 1, m_rtImg.top - 1);
		MemDC.LineTo(m_rtImg.left - 1, m_rtImg.bottom);
		MemDC.LineTo(m_rtImg.right, m_rtImg.bottom);
		MemDC.LineTo(m_rtImg.right, m_rtImg.top - 1);
		MemDC.LineTo(m_rtImg.left - 1, m_rtImg.top - 1);

		dc.BitBlt(m_rtCtrl.left, m_rtCtrl.top, m_rtCtrl.Width(), m_rtCtrl.Height(),
			&MemDC, m_rtCtrl.left, m_rtCtrl.top, SRCCOPY);
	}

	if ( nRedrawFlag & REDRAW_IMG )
	{
		DrawImg(&MemDC);
		dc.BitBlt(m_rtImg.left, m_rtImg.top, m_rtImg.Width(), m_rtImg.Height(),
			&MemDC, m_rtImg.left, m_rtImg.top, SRCCOPY);
	}

	if (nRedrawFlag & REDRAW_ZOOM)
	{
		DrawZoom(&MemDC);
		dc.BitBlt(m_rtZoom.left, m_rtZoom.top, m_rtZoom.Width(), m_rtZoom.Height(),
			&MemDC, m_rtZoom.left, m_rtZoom.top, SRCCOPY);
	}

	if (nRedrawFlag & REDRAW_BTN)
	{
		DrawBtn(&MemDC);
	}
	//将内存中的图拷贝到屏幕上进行显示
	//dc->BitBlt(m_rWave.left, m_rWave.top, nWidth, nHeight, &MemDC, 0, 0, SRCCOPY);

	MemDC.SelectObject(pOldBit);
	MemBitmap.DeleteObject();
	MemDC.DeleteDC();

	for (int i = 0; i < m_arrBtn.GetSize(); i++)		// 刷新按键区域
	{
		m_arrBtn[i]->InvalidateRect(NULL, FALSE);
	}

	return;
}

void CShowCrack::DrawImg(CDC* pDC)
{
	//m_imgOperator.DrawInfo(DRAW_ALL, false, m_dCoe);
	//m_imgOperator.DrawMat(pDC, m_rtImg, m_ptImg);
	m_imgOperator.ShowImage(pDC, m_rtImg, m_ptLeftTop, m_dCoe , m_dImgCoe);
}

void CShowCrack::DrawZoom(CDC* pDC)
{
	// 先刷新背景
	//pDC->FillSolidRect(m_rtZoom, RGB(255, 255, 255));

	/*CPen pen;
	CPen* pOldPen;
	
	pen.CreatePen(PS_SOLID, 5, RGB(0, 0, 0));

	pOldPen = pDC->SelectObject(&pen);

	pDC->MoveTo(m_arrPtZoomValue[0]);
	pDC->LineTo(m_arrPtZoomValue[m_arrPtZoomValue.GetSize() - 1]);

	pDC->SelectObject(pOldPen);
	pen.DeleteObject();
	pen.CreatePen(PS_SOLID, 3, RGB(0, 0, 0));
	pOldPen = pDC->SelectObject(&pen);

	CBrush  brushNormal, brushSel;
	CBrush* pOldBrush;
	brushNormal.CreateSolidBrush(RGB(255, 255, 255));
	brushSel.CreateSolidBrush(RGB(255, 255, 0));
	pOldBrush = pDC->SelectObject(&brushNormal);			// */

	PasteImg(pDC, strImgZoom, CRect(m_rtZoom.left + nRadiusOut - nRadiusIn,
		m_rtZoom.top, m_rtZoom.right + nRadiusIn - nRadiusOut, m_rtZoom.top + nRadiusOut * 2));

	CFont font;
	CFont* pOldFont;
	font.CreatePointFont(120, L"黑体");
	pOldFont = pDC->SelectObject(&font);
	pDC->SetBkMode(TRANSPARENT);
	for (int i = 0; i < m_arrPtZoomValue.GetSize(); i++)
	{
		POINT pt;
		pt = m_arrPtZoomValue.GetAt(i);
		int nSelCoe = (int)(ceil((m_dCoe - dZoomMin) / dZoomDiv));
		if (nSelCoe == i)
		{
			PasteImg(pDC, strImgZoomSel, CRect(pt.x - nRadiusOut, pt.y - nRadiusOut, pt.x + nRadiusOut, pt.y + nRadiusOut));
		}
		//if (nSelCoe == i)
		//{
		//	pDC->SelectObject(&brushSel);
		//}
		//else
		//{
		//	pDC->SelectObject(&brushNormal);
		//}
		//pDC->Ellipse(pt.x - nRadiusOut, pt.y - nRadiusOut, pt.x + nRadiusOut, pt.y + nRadiusOut);				// */

		CSize size;
		CString str;
		if (dZoomMin + dZoomDiv * i < dZoomMax)
		{
			str.Format(L"%.1f", dZoomMin + dZoomDiv * i);
		}
		else
		{
			str.Format(L"%.1f", dZoomMax);
		}
		size = pDC->GetTextExtent(str);
		pDC->TextOut(pt.x - size.cx / 2, pt.y + nRadiusOut, str);
	}
	//pDC->SelectObject(pOldPen);
	//pen.DeleteObject();
	//pDC->SelectObject(pOldBrush);
	//brushNormal.DeleteObject();
	//brushSel.DeleteObject();

	// 左右两边贴图
	//PasteImg(pDC, strZoomIn, m_rtBtnZoomIn);
	//PasteImg(pDC, strZoomOut, m_rtBtnZoomOut);
}

void CShowCrack::DrawBtn(CDC* pDC)
{
	//PasteImg(pDC, strBtnFront, m_rtBtnPrevious);
	//PasteImg(pDC, strBtnNext, m_rtBtnNext);
}

void CShowCrack::PasteImg(CDC* pDC, const CString& strBtnFileName, CRect& rect)
{
	CImage img;
	img.Load(strBtnFileName);
	CImgOperator::LoadPng(img);
	if(!img.IsNull())
		img.Draw(pDC->GetSafeHdc(), rect.left, rect.top + (rect.Height() - img.GetHeight()) / 2,
			rect.Width(), img.GetHeight());
}

void CShowCrack::CreateBtn()
{
	int nBtnStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | BS_BITMAP | BS_OWNERDRAW;
	CMyImgBtn* btnPrevious = new CMyImgBtn();
	btnPrevious->AddImage(strBtnPrevious, MAX_IMG_CNT);
	btnPrevious->Create(_T(""), nBtnStyle, m_rtBtnPrevious, this, IDC_BTN_PREVIOUS);
	m_arrBtn.Add(btnPrevious);

	CMyImgBtn* btnNext = new CMyImgBtn();
	btnNext->AddImage(strBtnNext, MAX_IMG_CNT);
	btnNext->Create(_T(""), nBtnStyle, m_rtBtnNext, this, IDC_BTN_NEXT);
	m_arrBtn.Add(btnNext);
	
	CMyImgBtn* btnZoomIn = new CMyImgBtn();
	btnZoomIn->AddImage(strZoomIn, MAX_IMG_CNT);
	btnZoomIn->Create(_T(""), nBtnStyle, m_rtBtnZoomIn, this, IDC_BTN_ZOOMIN);
	m_arrBtn.Add(btnZoomIn);

	CMyImgBtn* btnZoomOut = new CMyImgBtn();
	btnZoomOut->AddImage(strZoomOut, MAX_IMG_CNT);
	//nBtnStyle = WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON;
	btnZoomOut->Create(_T(""), nBtnStyle, m_rtBtnZoomOut, this, IDC_BTN_ZOOMOUT);
	m_arrBtn.Add(btnZoomOut);
}

void CShowCrack::DeleteBtn()
{
	for (int i = 0; i < m_arrBtn.GetSize(); i++)
	{
		delete m_arrBtn[i];
	}
	m_arrBtn.RemoveAll();
}

POINT CShowCrack::CalcMousePt(const CPoint& ptCur, const double& dCoeChange)
{
	POINT ptResult;
	/*ptLeftTop.x = (ptCur.x - m_rtImg.left) * (dCoeChange) / (m_dCoe - dCoeChange) / m_dCoe;
	ptLeftTop.y = (ptCur.y - m_rtImg.top) * (dCoeChange) / (m_dCoe - dCoeChange) / m_dCoe;

	m_ptLeftTop.x = (ptLeftTop.x + m_ptLeftTop.x / (m_dCoe - dCoeChange)) * m_dCoe;
	m_ptLeftTop.y = (ptLeftTop.y + m_ptLeftTop.y / (m_dCoe - dCoeChange)) * m_dCoe;

	if (m_dCoe == 1.0)
	{
		m_ptLeftTop.x = 0;
		m_ptLeftTop.y = 0;
	}
	TRACE(L"LeftTop Point(%d, %d)\n", m_ptLeftTop.x, m_ptLeftTop.y);*/

	ptResult.x = (int)(((ptCur.x - m_rtImg.left) / m_dImgCoe + m_ptLeftTop.x) / m_dCoe);
	ptResult.y = (int)(((ptCur.y - m_rtImg.top) / m_dImgCoe + m_ptLeftTop.y) / m_dCoe);

	//TRACE(L"Result Point(%d, %d)\n", ptResult.x, ptResult.y);

	return ptResult;
}

void CShowCrack::GetWidAndHeight(int &nHeight, int &nWid)
{
	int nIdx = g_GJData.GetSelGJId();

	CString strYiQiType = g_GJData.GetYiQiType(nIdx);

	if (strYiQiType == strYiQi_U8_1024_768)
	{
		nHeight = nImgHeight_U8;
		nWid = nImgWidth_U8;
	}
	else if (strYiQiType == strYiQi_U9_1280_800)
	{
		nHeight = nImgHeight_U9;
		nWid = nImgWidth_U9;
	}
	else if (strYiQiType == strYiQi_CK103_1280_720)
	{
		nHeight = nImgHeight;
		nWid = nImgWidth;
	}
}

void CShowCrack::CalcLeftTopPt(const CPoint& ptCur, const double& dCoeLast)
{
	double dPtx = (ptCur.x - m_rtImg.left) / m_dImgCoe * (m_dCoe - dCoeLast) / dCoeLast / m_dCoe;
	double dPty = (ptCur.y - m_rtImg.top) / m_dImgCoe * (m_dCoe - dCoeLast) / dCoeLast / m_dCoe;

	m_ptLeftTop.x = (int)((dPtx + m_ptLeftTop.x / dCoeLast) * m_dCoe);
	m_ptLeftTop.y = (int)((dPty + m_ptLeftTop.y / dCoeLast) * m_dCoe);

	if (m_ptLeftTop.x < 0) m_ptLeftTop.x = 0;
	if (m_ptLeftTop.y < 0) m_ptLeftTop.y = 0;

	int nHeight = 0, nWidht = 0;
	GetWidAndHeight(nHeight, nWidht);

	if (m_ptLeftTop.x + nWidht > nWidht * m_dCoe) m_ptLeftTop.x = (int)(nWidht * (m_dCoe - 1));
	if (m_ptLeftTop.y + nHeight > nHeight * m_dCoe) m_ptLeftTop.y = (int)(nHeight * (m_dCoe - 1));

	if (m_dCoe == dZoomMin)
	{
		m_ptLeftTop.x = 0;
		m_ptLeftTop.y = 0;
	}
	//TRACE(L"LeftTop Point(%d, %d)\n", m_ptLeftTop.x, m_ptLeftTop.y);
}

void CShowCrack::CalcDCoe(const double & dCoeChange)
{
	double dCoe = m_dCoe + dCoeChange;

	dCoe = dCoe < dZoomMin ? dZoomMin : dCoe;
	dCoe = dCoe > dZoomMax ? dZoomMax : dCoe;

	m_dCoe = dCoe;
}

BOOL CShowCrack::RegisterWndClass(HINSTANCE hInstance)
{
	WNDCLASS	windowClass;
	LPCWSTR		className = L"ShowCrack";				// 控件类的名字
	
	if (!hInstance)
	{
		hInstance = AfxGetInstanceHandle();
	}

	if (!(::GetClassInfo(hInstance, className, &windowClass)))
	{
		windowClass.style = CS_DBLCLKS;
		windowClass.lpfnWndProc = ::DefWindowProc;
		windowClass.cbClsExtra = windowClass.cbWndExtra = 0;
		windowClass.hInstance = hInstance;
		windowClass.hIcon = NULL;
		windowClass.hCursor = AfxGetApp()->LoadStandardCursor(IDC_ARROW);

		//windowClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
		windowClass.hbrBackground = (HBRUSH)(m_brBack.GetSafeHandle());
		windowClass.lpszMenuName = NULL;
		windowClass.lpszClassName = className;

		if (!AfxRegisterClass(&windowClass))
		{
			AfxThrowResourceException();
			return FALSE;
		}
	}

	return TRUE;
}

LRESULT CShowCrack::SendMessageToParent(int nMessage)
{
	if (!IsWindow(m_hWnd))
	{
		return 0;
	}
	
	NM_CRACKVIEW nmcv;
	memset(&nmcv, 0, sizeof(NM_CRACKVIEW));
	nmcv.hdr.hwndFrom = m_hWnd;
	nmcv.hdr.idFrom = GetDlgCtrlID();
	nmcv.hdr.code = nMessage;
	nmcv.ptCur1 = m_imgOperator.GetPoint1();
	nmcv.ptCur2 = m_imgOperator.GetPoint2();

	CWnd* pOwner = GetOwner();
	if (pOwner && IsWindow(pOwner->m_hWnd))
	{
		return pOwner->SendMessage(WM_NOTIFY, nmcv.hdr.idFrom, (LPARAM)&nmcv);
	}
	else
	{
		return 0;
	}
}


BEGIN_MESSAGE_MAP(CShowCrack, CWnd)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	ON_WM_MOUSEWHEEL()
	ON_COMMAND_RANGE(IDC_BTN_PREVIOUS, IDC_BTN_ZOOMOUT, OnButtonClick)//消息响应
	ON_MESSAGE(WM_USERME, &CShowCrack::OnInitTypeRect)
	ON_WM_ERASEBKGND()
END_MESSAGE_MAP()



// CShowCrack 消息处理程序




void CShowCrack::OnButtonClick(UINT uID)
{
	switch (uID)
	{
	case IDC_BTN_PREVIOUS:
		SendMessageToParent(CVN_PREVIOUSGJ);
		break;
	case IDC_BTN_NEXT:
		SendMessageToParent(CVN_NEXTGJ);
		break;
	case IDC_BTN_ZOOMIN:
		ZoomIn();
		break;
	case IDC_BTN_ZOOMOUT:
		ZoomOut();
		break;
	default:
		break;
	}
}

LRESULT CShowCrack::OnInitTypeRect(WPARAM wParam, LPARAM lParam)	//接受其他进程发来的消息
{
	int nValue = (int)wParam;
	if (nValue == 1)
	{
		int b = 0;
	}

	return TRUE;
}

void CShowCrack::OnPaint()
{
	CPaintDC dc(this); // device context for painting
					   // TODO: 在此处添加消息处理程序代码
					   // 不为绘图消息调用 CWnd::OnPaint()

	CRect rect;
	this->GetClientRect(rect);

	DrawCtrl(REDRAW_ALL);
}


void CShowCrack::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	// TODO: 在此处添加消息处理程序代码
	initRect();

	if (m_arrBtn.GetSize() <= 0)
	{
		CreateBtn();
	}

	m_arrBtn[0]->MoveWindow(m_rtBtnPrevious);
	m_arrBtn[1]->MoveWindow(m_rtBtnNext);
	m_arrBtn[2]->MoveWindow(m_rtBtnZoomIn);
	m_arrBtn[3]->MoveWindow(m_rtBtnZoomOut);
}

void CShowCrack::UpdateBtn()
{
	if (m_arrBtn.GetSize() <= 0)
	{
		CreateBtn();
	}

	m_arrBtn[0]->MoveWindow(m_rtBtnPrevious);
	m_arrBtn[1]->MoveWindow(m_rtBtnNext);
	m_arrBtn[2]->MoveWindow(m_rtBtnZoomIn);
	m_arrBtn[3]->MoveWindow(m_rtBtnZoomOut);
}

int CShowCrack::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  在此添加您专用的创建代码
	initRect();
	return 0;
}


void CShowCrack::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值

	for (int i = 0; i < m_arrPtZoomValue.GetSize(); i++)
	{
		POINT pt = m_arrPtZoomValue.GetAt(i);
		POINT ptTmp;
		ptTmp.x = point.x - m_rtImg.left;
		ptTmp.y = point.y - m_rtImg.top;
		if (abs(pt.x - point.x) < nRadiusOut && abs(pt.y - point.y) < nRadiusOut)
		{
			m_dCoe = (i * dZoomDiv + dZoomMin);
			
			m_ptLeftTop.x = (int)((m_dCoe - dZoomMin) * m_rtImg.Width() / m_dImgCoe / 2.0);
			m_ptLeftTop.y = (int)((m_dCoe - dZoomMin) * m_rtImg.Height() / m_dImgCoe / 2.0);

			int nHeight = 0, nWid = 0;
			GetWidAndHeight(nHeight, nWid);

			m_ptImgMouse.x = nWid / 2;
			m_ptImgMouse.y = nHeight / 2;
			DrawCtrl(REDRAW_IMG | REDRAW_ZOOM);
			return;
		}
	}

	//if (m_rtBtnPrevious.PtInRect(point))
	//{
	//	SendMessageToParent(CVN_PREVIOUSGJ);
	//	return;
	//}

	//if (m_rtBtnNext.PtInRect(point))
	//{
	//	SendMessageToParent(CVN_NEXTGJ);
	//	return;
	//}

	//if (m_rtBtnZoomIn.PtInRect(point))
	//{
	//	CPoint ptCur;
	//	ptCur.x = m_rtImg.left + nImgWidth / 2;
	//	ptCur.y = m_rtImg.top + nImgHeight / 2;
	//	
	//	double dCoeLast = m_dCoe;
	//	CalcDCoe((-1) * dZoomDiv);
	//	CalcLeftTopPt(ptCur, dCoeLast);
	//	DrawCtrl(REDRAW_IMG | REDRAW_ZOOM);
	//}

	//if (m_rtBtnZoomOut.PtInRect(point))
	//{
	//	CPoint ptCur;
	//	ptCur.x = m_rtImg.left + nImgWidth / 2;
	//	ptCur.y = m_rtImg.top + nImgHeight / 2;

	//	double dCoeLast = m_dCoe;
	//	CalcDCoe(dZoomDiv);
	//	CalcLeftTopPt(ptCur, dCoeLast);
	//	DrawCtrl(REDRAW_IMG | REDRAW_ZOOM);
	//}

	if (m_bPtSel)
	{
		m_bPtSel = FALSE;
		m_nCurSelPt = 0;

		HCURSOR hCur = LoadCursor(NULL, IDC_ARROW);
		::SetCursor(hCur);
	}

	if (m_rtImg.PtInRect(point))// && m_dCoe > dZoomMin)
	{
		m_ptLBtnDown = point;

		if (m_nCurSelPt == 0)
		{
			m_bLBtnDown = TRUE;
			//HCURSOR hCur = LoadCursor(NULL, IDC_HAND);
			//::SetCursor(hCur);
		}
	}

	this->SetFocus();
	CWnd::OnLButtonDown(nFlags, point);
}


void CShowCrack::OnLButtonUp(UINT nFlags, CPoint point)
{
	if (m_nCurSelPt > 0 && point == m_ptLBtnDown)
	{
		m_bPtSel = TRUE;
		HCURSOR hCur = LoadCursor(NULL, IDC_SIZEALL);
		::SetCursor(hCur);
		//m_nCurSelPt = m_nTmpSelPt;
	}
	else
	{
		m_bPtSel = FALSE;
		//m_nCurSelPt = 0;
	}

	if (m_bLBtnDown)
	{
		HCURSOR hCur = LoadCursor(NULL, IDC_ARROW);
		::SetCursor(hCur);
		m_bLBtnDown = FALSE;
	}

	CWnd::OnLButtonUp(nFlags, point);
}


void CShowCrack::OnMouseMove(UINT nFlags, CPoint point)
{
#ifdef _DEBUG
	CClientDC dc(this);					// 增加双缓冲绘图 避免闪烁
	CString str;
	POINT pt = CalcMousePt(point, 0);		//point为绘图区域点，
	str.Format(L"CurPoint(%03d, %03d), MousePoint(%03d, %03d)", point.x, point.y, pt.x, pt.y);
	dc.TextOut(0, 0, str);
#endif // _DEBUG

	/*m_nCurSelPt = 0;
	if (nFlags & MK_CONTROL)
	{
		//int	nCurSelPt = 0;
		POINT ptCrack1, ptCrack2, ptCur;
		ptCrack1 = m_imgOperator.GetPoint1();
		ptCrack2 = m_imgOperator.GetPoint2();
		ptCur = CalcMousePt(point, 0);
		if (ptCur.x > 0 && ptCur.y > 0 && abs(ptCur.x - ptCrack1.x) < nJudge && abs(ptCur.y - ptCrack1.y) < nJudge)
		{
			HCURSOR hCur = LoadCursor(NULL, IDC_SIZEALL);
			::SetCursor(hCur);
			m_nCurSelPt = 1;
			if (m_bLBtnDown)
			{
				m_imgOperator.SetPoint1(ptCur);

				SendMessageToParent(CVN_PTCHANGED);
				m_imgOperator.SetImgInfo(m_nCurGJ, false);
			}
		}

		if (ptCur.x > 0 && ptCur.y > 0 && abs(ptCur.x - ptCrack2.x) < nJudge && abs(ptCur.y - ptCrack2.y) < nJudge)
		{
			HCURSOR hCur = LoadCursor(NULL, IDC_SIZEALL);
			::SetCursor(hCur);
			m_nCurSelPt = 2;
			if (m_bLBtnDown)
			{
				m_imgOperator.SetPoint2(ptCur);
				SendMessageToParent(CVN_PTCHANGED);
				m_imgOperator.SetImgInfo(m_nCurGJ, false);
			}
		}
	}			// */

	POINT ptCur = CalcMousePt(point, 0);
	if (m_bPtSel)
	{
		HCURSOR hCur = LoadCursor(NULL, IDC_SIZEALL);
		::SetCursor(hCur);
		switch (m_nCurSelPt)
		{
		case 1:
			m_imgOperator.SetPoint1(ptCur);
			SendMessageToParent(CVN_PTCHANGED);
			m_imgOperator.SetImgInfo(m_nCurGJ, false);
			break;
		case 2:
			m_imgOperator.SetPoint2(ptCur);
			SendMessageToParent(CVN_PTCHANGED);
			m_imgOperator.SetImgInfo(m_nCurGJ, false);
			break;
		default:
			break;
		}
	}
	else
	{
		m_nCurSelPt = 0;
		POINT ptCrack1, ptCrack2; //ptCur;
		ptCrack1 = m_imgOperator.GetPoint1();
		ptCrack2 = m_imgOperator.GetPoint2();
		//ptCur = CalcMousePt(point, 0);
		if (ptCur.x > 0 && ptCur.y > 0 && abs(ptCur.x - ptCrack1.x) < nJudge && abs(ptCur.y - ptCrack1.y) < nJudge)
		{
			m_nCurSelPt = 1;
		}
		if (ptCur.x > 0 && ptCur.y > 0 && abs(ptCur.x - ptCrack2.x) < nJudge && abs(ptCur.y - ptCrack2.y) < nJudge)
		{
			m_nCurSelPt = 2;
		}
	}

	if (m_nCurSelPt != m_nLastSelPt || m_nCurSelPt > 0)
	{
		//m_imgOperator.SetImgInfo(m_nCurGJ, false);
		m_imgOperator.DrawCrackInfo(DRAW_CRACK | DRAW_CRACKRULE | DRAW_CRACKWIDTH, m_nCurSelPt, m_bGray);
		m_nLastSelPt = m_nCurSelPt;
		DrawCtrl(REDRAW_IMG);
		return;
	}

	if (m_bLBtnDown && m_rtImg.PtInRect(point) && m_dCoe > dZoomMin)
	{
		HCURSOR hCur = LoadCursor(NULL, IDC_HAND);
		::SetCursor(hCur);

		m_ptLeftTop.x = (int)(m_ptLeftTop.x - (point.x - m_ptLBtnDown.x) / m_dImgCoe);
		m_ptLeftTop.y = (int)(m_ptLeftTop.y - (point.y - m_ptLBtnDown.y) / m_dImgCoe);

		m_ptLBtnDown = point;

		if (m_ptLeftTop.x < 0) m_ptLeftTop.x = 0;
		if (m_ptLeftTop.y < 0) m_ptLeftTop.y = 0;

		int nHeight = 0, nWid = 0;
		GetWidAndHeight(nHeight, nWid);

		if (m_ptLeftTop.x + nWid > nWid * m_dCoe) m_ptLeftTop.x = (int)(nWid * (m_dCoe - 1));
		if (m_ptLeftTop.y + nHeight > nHeight * m_dCoe) m_ptLeftTop.y = (int)(nHeight * (m_dCoe - 1));

		DrawCtrl(REDRAW_IMG);
		return;
	}

	CWnd::OnMouseMove(nFlags, point);
}


BOOL CShowCrack::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CPoint point(pt);
	ScreenToClient(&point);
	if (m_rtImg.PtInRect(point))
	{
		//TRACE(L"\nPoint(%d, %d)\n", point.x, point.y);

		double dCoeLast = m_dCoe;

		int nValue = zDelta / abs(zDelta);

		CalcDCoe(nValue * dZoomDiv);
		//m_dCoe = m_dCoe + nValue * dZoomDiv;

		//m_dCoe = m_dCoe < dZoomMin ? dZoomMin : m_dCoe;
		//m_dCoe = m_dCoe > dZoomMax ? dZoomMax : m_dCoe;

		if (m_dCoe != dCoeLast)
		{
			/*double dPtx = (point.x - m_rtImg.left) * (m_dCoe - dCoeLast) / dCoeLast / m_dCoe;
			double dPty = (point.y - m_rtImg.top) * (m_dCoe - dCoeLast) / dCoeLast / m_dCoe;

			m_ptLeftTop.x = (int)((dPtx + m_ptLeftTop.x / dCoeLast) * m_dCoe);
			m_ptLeftTop.y = (int)((dPty + m_ptLeftTop.y / dCoeLast) * m_dCoe);

			if (m_ptLeftTop.x < 0) m_ptLeftTop.x = 0;
			if (m_ptLeftTop.y < 0) m_ptLeftTop.y = 0;

			if (m_ptLeftTop.x + m_rtImg.Width() > nImgWidth * m_dCoe) m_ptLeftTop.x = (int)(m_rtImg.Width() * (m_dCoe - 1));
			if (m_ptLeftTop.y + m_rtImg.Height() * m_dImgCoe > nImgHeight * m_dCoe) m_ptLeftTop.y = (int)(m_rtImg.Height() * (m_dCoe - 1));

			if (m_dCoe == 1.0)
			{
				m_ptLeftTop.x = 0;
				m_ptLeftTop.y = 0;
			}
			TRACE(L"LeftTop Point(%d, %d)\n", m_ptLeftTop.x, m_ptLeftTop.y);*/
			CalcLeftTopPt(point, dCoeLast);
			m_ptImgMouse = CalcMousePt(point, m_dCoe - dCoeLast);
			DrawCtrl(REDRAW_IMG | REDRAW_ZOOM);
		}
	}
	

	return CWnd::OnMouseWheel(nFlags, zDelta, pt);
}


BOOL CShowCrack::OnEraseBkgnd(CDC* pDC)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	this->GetClientRect(m_rtCtrl);
	pDC->FillSolidRect(m_rtCtrl, RGB(255, 255, 255));
	return false;
	return CWnd::OnEraseBkgnd(pDC);
}
